package cn.spring.theLogger;


import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;


import java.util.Arrays;

@Aspect
public class ErrorLogger {
    private static final Logger logger = Logger.getLogger(ErrorLogger.class);

    @Pointcut("execution(* cn.spring.service..*.*(..))")
    public void pointcut(){}

//    前置增强
//    @Before("execution(* cn.spring.service..*.*(..))")
    @Before("pointcut()")
    public void before(JoinPoint jp){
        logger.debug("调用"+jp.getTarget()+"的"+jp.getSignature().getName()
        +"方法。方法入参："+Arrays.toString(jp.getArgs()));
    }

//    后置增强
//    @AfterReturning(pointcut = "execution(* cn.spring.service..*.*(..))",returning = "returnValue")
    @AfterReturning(pointcut = "pointcut()",returning = "returnValue")
    public void afterReturning(JoinPoint jp,Object returnValue){
        logger.debug("调用"+jp.getTarget()+"的" + jp.getSignature().getName()+
                "方法。方法返回值：" + returnValue);
    }
//    异常增强
    public void afterThrowing(JoinPoint jp,RuntimeException e){
        logger.debug(jp.getSignature().getName()+"方法异常："+e);
    }
//    最终增强
    public void afterLogger(JoinPoint jp){
        logger.debug(jp.getSignature().getName()+"方法结束执行。");
    }

//    环绕增强
    public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable{
        logger.debug("调用"+jp.getTarget()+"的" +jp.getSignature().getName()
        +"方法。方法入参："+ Arrays.toString(jp.getArgs()));
        try {
            Object result = jp.proceed();   //执行目标方法并获得其返回值
            logger.debug("调用"+jp.getTarget()+"的"+jp.getSignature().getName()
            +"方法。方法返回值："+result);
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw throwable;
        } finally {
            logger.debug(jp.getSignature().getName()+"方法执行结束。");
        }
    }
}
